home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / phillip2 / edges.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-11  |  38.2 KB  |  1,563 lines

  1.  
  2.    /*************************** 
  3.    * 
  4.    *   edges.c 
  5.    *   COMPOSITE FILE COMPRISING: 
  6.    *   edge.c 
  7.    *   edge2.c 
  8.    *   edge3.c 
  9.    * 
  10.    ***************************\ 
  11.  
  12.  
  13.  
  14.  
  15.        /***********************************************
  16.        *
  17.        *       file d:\cips\edge.c
  18.        *
  19.        *       Functions: This file contains
  20.        *          detect_edges
  21.        *          setup_masks
  22.        *          get_edge_options
  23.        *          perform_convolution
  24.        *          quick_edge
  25.        *          fix_edges
  26.        *
  27.        *       Purpose:
  28.        *          These functions implement several
  29.        *          types of basic edge detection.
  30.        *
  31.        *       External Calls:
  32.        *          wtiff.c - round_off_image_size
  33.        *                    create_file_if_needed
  34.        *                    write_array_into_tiff_image
  35.        *          tiff.c - read_tiff_header
  36.        *          rtiff.c - read_tiff_image
  37.        *          numcvrt.c - get_integer
  38.        *
  39.        *
  40.        *       Modifications:
  41.        *          27 January 1991 - created
  42.        *          27 December 1992 - Fixed an error in
  43.        *              how I did the 8 direction edge
  44.        *              detectors.  I was only detecting
  45.        *              edges in the last (the 7)
  46.        *              direction.  I fixed this by
  47.        *              setting the out_image to the sum
  48.        *              only if the sum was greater than
  49.        *              the out_image.  This is in the
  50.        *              function perform_convolution.
  51.        *
  52.        *************************************************/
  53.  
  54. #include "cips.h"
  55.  
  56.  
  57.  
  58.  
  59.  
  60. short quick_mask[3][3] =  {
  61.        {-1,  0, -1},
  62.        { 0,  4,  0},
  63.        {-1,  0, -1} };
  64.  
  65.  
  66.    /***************************
  67.    *
  68.    *   Directions for the masks
  69.    *  3 2 1
  70.    *  4 x 0
  71.    *  5 6 7
  72.    *
  73.    ****************************/
  74.  
  75.    /* masks for kirsch operator */
  76. short kirsch_mask_0[3][3] =  {
  77.        { 5,  5,  5},
  78.        {-3,  0, -3},
  79.        {-3, -3, -3} };
  80.  
  81. short kirsch_mask_1[3][3] =  {
  82.        {-3,  5,  5},
  83.        {-3,  0,  5},
  84.        {-3, -3, -3} };
  85.  
  86. short kirsch_mask_2[3][3] =  {
  87.        {-3, -3,  5},
  88.        {-3,  0,  5},
  89.        {-3, -3,  5} };
  90.  
  91. short kirsch_mask_3[3][3] =  {
  92.        {-3, -3, -3},
  93.        {-3,  0,  5},
  94.        {-3,  5,  5} };
  95.  
  96. short kirsch_mask_4[3][3] =  {
  97.        {-3, -3, -3},
  98.        {-3,  0, -3},
  99.        { 5,  5,  5} };
  100.  
  101. short kirsch_mask_5[3][3] =  {
  102.        {-3, -3, -3},
  103.        { 5,  0, -3},
  104.        { 5,  5, -3} };
  105.  
  106. short kirsch_mask_6[3][3] =  {
  107.        { 5, -3, -3},
  108.        { 5,  0, -3},
  109.        { 5, -3, -3} };
  110.  
  111. short kirsch_mask_7[3][3] =  {
  112.        { 5,  5, -3},
  113.        { 5,  0, -3},
  114.        {-3, -3, -3} };
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.    /* masks for prewitt operator */
  122.  
  123. short prewitt_mask_0[3][3] =  {
  124.        { 1,  1,  1},
  125.        { 1, -2,  1},
  126.        {-1, -1, -1} };
  127.  
  128. short prewitt_mask_1[3][3] =  {
  129.        { 1,  1,  1},
  130.        { 1, -2, -1},
  131.        { 1, -1, -1} };
  132.  
  133. short prewitt_mask_2[3][3] =  {
  134.        { 1,  1, -1},
  135.        { 1, -2, -1},
  136.        { 1,  1, -1} };
  137.  
  138. short prewitt_mask_3[3][3] =  {
  139.        { 1, -1, -1},
  140.        { 1, -2, -1},
  141.        { 1,  1,  1} };
  142.  
  143. short prewitt_mask_4[3][3] =  {
  144.        {-1, -1, -1},
  145.        { 1, -2,  1},
  146.        { 1,  1,  1} };
  147.  
  148. short prewitt_mask_5[3][3] =  {
  149.        {-1, -1,  1},
  150.        {-1, -2,  1},
  151.        { 1,  1,  1} };
  152.  
  153. short prewitt_mask_6[3][3] =  {
  154.        {-1,  1,  1},
  155.        {-1, -2,  1},
  156.        {-1,  1,  1} };
  157.  
  158. short prewitt_mask_7[3][3] =  {
  159.        { 1,  1,  1},
  160.        {-1, -2,  1},
  161.        {-1, -1,  1} };
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.    /* masks for sobel operator */
  169.  
  170. short sobel_mask_0[3][3] =  {
  171.        { 1,  2,  1},
  172.        { 0,  0,  0},
  173.        {-1, -2, -1} };
  174.  
  175. short sobel_mask_1[3][3] =  {
  176.        { 2,  1,  0},
  177.        { 1,  0, -1},
  178.        { 0, -1, -2} };
  179.  
  180. short sobel_mask_2[3][3] =  {
  181.        { 1,  0, -1},
  182.        { 2,  0, -2},
  183.        { 1,  0, -1} };
  184. short sobel_mask_3[3][3] =  {
  185.        { 0, -1, -2},
  186.        { 1,  0, -1},
  187.        { 2,  1,  0} };
  188.  
  189. short sobel_mask_4[3][3] =  {
  190.        {-1, -2, -1},
  191.        { 0,  0,  0},
  192.        { 1,  2,  1} };
  193.  
  194. short sobel_mask_5[3][3] =  {
  195.        {-2, -1,  0},
  196.        {-1,  0,  1},
  197.        { 0,  1,  2} };
  198.  
  199. short sobel_mask_6[3][3] =  {
  200.        {-1,  0,  1},
  201.        {-2,  0,  2},
  202.        {-1,  0,  1} };
  203.  
  204. short sobel_mask_7[3][3] =  {
  205.        { 0,  1,  2},
  206.        {-1,  0,  1},
  207.        {-2, -1,  0} };
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.   /**************************************************
  215.   *
  216.   *   detect_edges(...
  217.   *
  218.   *   This function detects edges in an area of one
  219.   *   image and sends the result to another image
  220.   *   on disk.  It reads the input image from disk,
  221.   *   calls a convolution function, and then writes
  222.   *   the result out to disk.  If needed, it
  223.   *   allocates space on disk for the output image.
  224.   *
  225.   ***************************************************/
  226.  
  227.  
  228.  
  229.  
  230. detect_edges(in_name, out_name, the_image, out_image,
  231.              il, ie, ll, le, detect_type, threshold,
  232.              high)
  233.    char   in_name[], out_name[];
  234.    int    detect_type, high, il, ie,
  235.           ll, le, threshold;
  236.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  237.  
  238. {
  239.    int    i, j, k, length, width;
  240.    struct tiff_header_struct image_header;
  241.  
  242.  
  243.    create_file_if_needed(in_name, out_name, out_image);
  244.  
  245.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  246.  
  247.    read_tiff_header(in_name, &image_header);
  248.  
  249.    perform_convolution(the_image, out_image,
  250.                        detect_type, threshold,
  251.                        &image_header, high);
  252.  
  253.    fix_edges(out_image, 1);
  254.  
  255.    write_array_into_tiff_image(out_name, out_image,
  256.                                il, ie, ll, le);
  257. }  /* ends detect_edges */
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.      /**********************************************************
  266.      *
  267.      *   perform_convolution(...
  268.      *
  269.      *   This function performs convolution between the input
  270.      *   image and 8 3x3 masks.  The result is placed in
  271.      *   the out_image.
  272.      *
  273.      ********************************************************/
  274.  
  275. perform_convolution(image, out_image,
  276.                     detect_type, threshold,
  277.                     image_header, high)
  278.    short image[ROWS][COLS],
  279.          out_image[ROWS][COLS];
  280.    int   detect_type, high, threshold;
  281.    struct tiff_header_struct *image_header;
  282. {
  283.  
  284.    int a,
  285.        b,
  286.        i,
  287.        is_present,
  288.        j,
  289.        sum;
  290.  
  291.    short  mask_0[3][3],
  292.           mask_1[3][3],
  293.           mask_2[3][3],
  294.           mask_3[3][3],
  295.           mask_4[3][3],
  296.           mask_5[3][3],
  297.           mask_6[3][3],
  298.           mask_7[3][3],
  299.           max,
  300.           min,
  301.           new_hi,
  302.           new_low;
  303.  
  304.  
  305.    setup_masks(detect_type, mask_0, mask_1,
  306.                mask_2, mask_3, mask_4, mask_5,
  307.                mask_6, mask_7);
  308.  
  309.    new_hi  = 250;
  310.    new_low = 16;
  311.    if(image_header->bits_per_pixel == 4){
  312.        new_hi  = 10;
  313.        new_low = 3;
  314.    }
  315.  
  316.    min = 0;
  317.    max = 255;
  318.    if(image_header->bits_per_pixel == 4)
  319.       max = 16;
  320.  
  321.      /* clear output image array */
  322.    for(i=0; i<ROWS; i++)
  323.       for(j=0; j<COLS; j++)
  324.          out_image[i][j] = 0;
  325.  
  326.    printf("\n ");
  327.  
  328.    for(i=1; i<ROWS-1; i++){
  329.       if( (i%10) == 0) printf("%3d", i);
  330.       for(j=1; j<COLS-1; j++){
  331.  
  332.  
  333.          /* Convolve for all 8 directions */
  334.  
  335.          /* 0 direction */
  336.  
  337.       sum = 0;
  338.       for(a=-1; a<2; a++){
  339.          for(b=-1; b<2; b++){
  340.             sum = sum + image[i+a][j+b] *
  341.                   mask_0[a+1][b+1];
  342.          }
  343.       }
  344.          if(sum > max) sum = max;
  345.          if(sum < 0)   sum = 0;
  346.             /* Correction 12-27-92
  347.                see file header for
  348.                details. */
  349.       if(sum > out_image[i][j])
  350.          out_image[i][j]   = sum;
  351.  
  352.  
  353.          /* 1 direction */
  354.  
  355.       sum = 0;
  356.       for(a=-1; a<2; a++){
  357.          for(b=-1; b<2; b++){
  358.             sum = sum + image[i+a][j+b] * mask_1[a+1][b+1];
  359.          }
  360.       }
  361.          if(sum > max) sum = max;
  362.          if(sum < 0)   sum = 0;
  363.             /* Correction 12-27-92
  364.                see file header for
  365.                details. */
  366.       if(sum > out_image[i][j])
  367.          out_image[i][j]   = sum;
  368.  
  369.  
  370.          /* 2 direction */
  371.  
  372.       sum = 0;
  373.       for(a=-1; a<2; a++){
  374.          for(b=-1; b<2; b++){
  375.             sum = sum + image[i+a][j+b] * mask_2[a+1][b+1];
  376.          }
  377.       }
  378.          if(sum > max) sum = max;
  379.          if(sum < 0)   sum = 0;
  380.             /* Correction 12-27-92
  381.                see file header for
  382.                details. */
  383.       if(sum > out_image[i][j])
  384.          out_image[i][j]   = sum;
  385.  
  386.  
  387.          /* 3 direction */
  388.  
  389.       sum = 0;
  390.       for(a=-1; a<2; a++){
  391.          for(b=-1; b<2; b++){
  392.             sum = sum + image[i+a][j+b] * mask_3[a+1][b+1];
  393.          }
  394.       }
  395.          if(sum > max) sum = max;
  396.          if(sum < 0)   sum = 0;
  397.             /* Correction 12-27-92
  398.                see file header for
  399.                details. */
  400.       if(sum > out_image[i][j])
  401.          out_image[i][j]   = sum;
  402.  
  403.  
  404.          /* 4 direction */
  405.  
  406.       sum = 0;
  407.       for(a=-1; a<2; a++){
  408.          for(b=-1; b<2; b++){
  409.             sum = sum + image[i+a][j+b] * mask_4[a+1][b+1];
  410.          }
  411.       }
  412.          if(sum > max) sum = max;
  413.          if(sum < 0)   sum = 0;
  414.             /* Correction 12-27-92
  415.                see file header for
  416.                details. */
  417.       if(sum > out_image[i][j])
  418.          out_image[i][j]   = sum;
  419.  
  420.  
  421.          /* 5 direction */
  422.  
  423.       sum = 0;
  424.       for(a=-1; a<2; a++){
  425.          for(b=-1; b<2; b++){
  426.             sum = sum + image[i+a][j+b] * mask_5[a+1][b+1];
  427.          }
  428.       }
  429.          if(sum > max) sum = max;
  430.          if(sum < 0)   sum = 0;
  431.             /* Correction 12-27-92
  432.                see file header for
  433.                details. */
  434.       if(sum > out_image[i][j])
  435.          out_image[i][j]   = sum;
  436.  
  437.  
  438.          /* 6 direction */
  439.       sum = 0;
  440.       for(a=-1; a<2; a++){
  441.          for(b=-1; b<2; b++){
  442.             sum = sum + image[i+a][j+b] * mask_6[a+1][b+1];
  443.          }
  444.       }
  445.          if(sum > max) sum = max;
  446.          if(sum < 0)   sum = 0;
  447.             /* Correction 12-27-92
  448.                see file header for
  449.                details. */
  450.       if(sum > out_image[i][j])
  451.          out_image[i][j]   = sum;
  452.  
  453.  
  454.          /* 7 direction */
  455.  
  456.       sum = 0;
  457.       for(a=-1; a<2; a++){
  458.          for(b=-1; b<2; b++){
  459.             sum = sum + image[i+a][j+b] * mask_7[a+1][b+1];
  460.          }
  461.       }
  462.          if(sum > max) sum = max;
  463.          if(sum < 0)   sum = 0;
  464.             /* Correction 12-27-92
  465.                see file header for
  466.                details. */
  467.       if(sum > out_image[i][j])
  468.          out_image[i][j]   = sum;
  469.  
  470.  
  471.       }  /* ends loop over j */
  472.    }  /* ends loop over i */
  473.  
  474.  
  475.      /* if desired, threshold the output image */
  476.    if(threshold == 1){
  477.        for(i=0; i<ROWS; i++){
  478.           for(j=0; j<COLS; j++){
  479.              if(out_image[i][j] > high){
  480.                   out_image[i][j] = new_hi;
  481.              }
  482.              else{
  483.                   out_image[i][j] = new_low;
  484.              }
  485.           }
  486.        }
  487.    }  /* ends if threshold == 1 */
  488.  
  489. }  /* ends perform_convolution */
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.      /*******************************************
  498.      *
  499.      *   quick_edge(...
  500.      *
  501.      *   This function finds edges by using
  502.      *   a single 3x3 mask.
  503.      *
  504.      *******************************************/
  505.  
  506.  
  507. quick_edge(in_name, out_name, the_image, out_image,
  508.              il, ie, ll, le, threshold, high)
  509.    char   in_name[], out_name[];
  510.    int    high, il, ie, ll, le, threshold;
  511.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  512.  
  513. {
  514.    int    a, b, i, j, k,
  515.           length, max, new_hi, new_low,
  516.           sum, width;
  517.    struct tiff_header_struct image_header;
  518.  
  519.  
  520.    create_file_if_needed(in_name, out_name, out_image);
  521.  
  522.    read_tiff_header(in_name, &image_header);
  523.    new_hi  = 250;
  524.    new_low = 16;
  525.    if(image_header.bits_per_pixel == 4){
  526.        new_hi  = 10;
  527.        new_low = 3;
  528.    }
  529.  
  530.    max = 255;
  531.    if(image_header.bits_per_pixel == 4)
  532.       max = 16;
  533.  
  534.  
  535.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  536.  
  537.          /* Do convolution over image array */
  538.    printf("\n");
  539.    for(i=1; i<ROWS-1; i++){
  540.       if( (i%10) == 0) printf("%d ", i);
  541.       for(j=1; j<COLS-1; j++){
  542.          sum = 0;
  543.          for(a=-1; a<2; a++){
  544.             for(b=-1; b<2; b++){
  545.                sum = sum +
  546.                      the_image[i+a][j+b] *
  547.                      quick_mask[a+1][b+1];
  548.             }
  549.          }
  550.          if(sum < 0)   sum = 0;
  551.          if(sum > max) sum = max;
  552.          out_image[i][j]   = sum;
  553.  
  554.       }  /* ends loop over j */
  555.    }  /* ends loop over i */
  556.  
  557.      /* if desired, threshold the output image */
  558.    if(threshold == 1){
  559.        for(i=0; i<ROWS; i++){
  560.           for(j=0; j<COLS; j++){
  561.              if(out_image[i][j] > high){
  562.                   out_image[i][j] = new_hi;
  563.              }
  564.              else{
  565.                   out_image[i][j] = new_low;
  566.              }
  567.           }
  568.        }
  569.    }  /* ends if threshold == 1 */
  570.  
  571.    fix_edges(out_image, 1);
  572.  
  573.    write_array_into_tiff_image(out_name, out_image,
  574.                                il, ie, ll, le);
  575.  
  576. }  /* ends quick_edge */
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.    /***********************************************
  586.     *
  587.     *    setup_masks(...
  588.     *
  589.     *    This function copies the mask values defined
  590.     *    at the top of this file into the mask
  591.     *    arrays mask_0 through mask_7.
  592.     *
  593.     ***********************************************/
  594.  
  595.  
  596.  
  597. setup_masks(detect_type, mask_0, mask_1, mask_2, mask_3,
  598.             mask_4, mask_5, mask_6, mask_7)
  599.    int    detect_type;
  600.    short  mask_0[3][3],
  601.           mask_1[3][3],
  602.           mask_2[3][3],
  603.           mask_3[3][3],
  604.           mask_4[3][3],
  605.           mask_5[3][3],
  606.           mask_6[3][3],
  607.           mask_7[3][3];
  608. {
  609.    int i, j;
  610.  
  611.    if(detect_type == KIRSCH){
  612.       for(i=0; i<3; i++){
  613.         for(j=0; j<3; j++){
  614.           mask_0[i][j] = kirsch_mask_0[i][j];
  615.           mask_1[i][j] = kirsch_mask_1[i][j];
  616.           mask_2[i][j] = kirsch_mask_2[i][j];
  617.           mask_3[i][j] = kirsch_mask_3[i][j];
  618.           mask_4[i][j] = kirsch_mask_4[i][j];
  619.           mask_5[i][j] = kirsch_mask_5[i][j];
  620.           mask_6[i][j] = kirsch_mask_6[i][j];
  621.           mask_7[i][j] = kirsch_mask_7[i][j];
  622.         }
  623.       }
  624.    }  /* ends if detect_type == KIRSCH */
  625.  
  626.  
  627.    if(detect_type == PREWITT){
  628.       for(i=0; i<3; i++){
  629.         for(j=0; j<3; j++){
  630.           mask_0[i][j] = prewitt_mask_0[i][j];
  631.           mask_1[i][j] = prewitt_mask_1[i][j];
  632.           mask_2[i][j] = prewitt_mask_2[i][j];
  633.           mask_3[i][j] = prewitt_mask_3[i][j];
  634.           mask_4[i][j] = prewitt_mask_4[i][j];
  635.           mask_5[i][j] = prewitt_mask_5[i][j];
  636.           mask_6[i][j] = prewitt_mask_6[i][j];
  637.           mask_7[i][j] = prewitt_mask_7[i][j];
  638.         }
  639.       }
  640.    }  /* ends if detect_type == PREWITT */
  641.  
  642.  
  643.    if(detect_type == SOBEL){
  644.       for(i=0; i<3; i++){
  645.         for(j=0; j<3; j++){
  646.           mask_0[i][j] = sobel_mask_0[i][j];
  647.           mask_1[i][j] = sobel_mask_1[i][j];
  648.           mask_2[i][j] = sobel_mask_2[i][j];
  649.           mask_3[i][j] = sobel_mask_3[i][j];
  650.           mask_4[i][j] = sobel_mask_4[i][j];
  651.           mask_5[i][j] = sobel_mask_5[i][j];
  652.           mask_6[i][j] = sobel_mask_6[i][j];
  653.           mask_7[i][j] = sobel_mask_7[i][j];
  654.         }
  655.       }
  656.    }  /* ends if detect_type == SOBEL */
  657.  
  658.  
  659.  
  660. }  /* ends setup_masks */
  661.  
  662.  
  663.  
  664.    /***********************************************
  665.     *
  666.     *    get_edge_options(...
  667.     *
  668.     *    This function queries the user for the
  669.     *    parameters need to perform edge
  670.     *    detection.
  671.     *
  672.     ***********************************************/
  673.  
  674.  
  675. get_edge_options(detect_type, threshold, high, size)
  676.     int *detect_type, *high, *size, *threshold;
  677. {
  678.     int not_finished, response;
  679.     not_finished = 1;
  680.     while(not_finished){
  681.  
  682.       printf("\nThe Edge Detector options are:\n");
  683.       printf("\n\t1.  Type of edge detector is %d", *detect_type);
  684.       printf("\n\t      (recall 1=Prewitt     2=Kirsch");
  685.       printf("\n\t              3=Sobel       4=quick");
  686.       printf("\n\t              5=homogeneity 6=difference");
  687.       printf("\n\t              7=contrast    8=gaussian");
  688.       printf("\n\t              10=range      11=variance");
  689.       printf("\n\t2.  Threshold output is %d (0=off 1=on)", *threshold);
  690.       printf("\n\t3.  High threshold is %d", *high);
  691.       printf("\n\t4.  Size is %d (gaussian only)", *size);
  692.       printf("\n\nEnter choice (0 = no change) _\b");
  693.  
  694.  
  695.       get_integer(&response);
  696.  
  697.       if(response == 0){
  698.         not_finished = 0;
  699.       }
  700.  
  701.  
  702.       if(response == 1){
  703.         printf("\n\nEnter type of edge detector");
  704.         printf("\n\t      (recall 1=Prewitt     2=Kirsch");
  705.         printf("\n\t              3=Sobel       4=quick");
  706.         printf("\n\t              5=homogeneity 6=difference");
  707.         printf("\n\t              7=contrast    8=gaussian");
  708.         printf("\n\t              10=range      11=variance");
  709.         printf("\n  _\b");
  710.         get_integer(detect_type);
  711.       }
  712.  
  713.       if(response == 2){
  714.         printf("\n\nEnter threshold output (0=off 1=on)");
  715.         printf("\n  _\b");
  716.         get_integer(threshold);
  717.       }
  718.  
  719.       if(response == 3){
  720.         printf("\n\nEnter high threshold");
  721.         printf("\n  _\b");
  722.         get_integer(high);
  723.       }
  724.  
  725.       if(response == 4){
  726.         printf("\n\nEnter size for gaussian (7 or 9)");
  727.         printf("\n  _\b");
  728.         get_integer(size);
  729.       }
  730.     }  /* ends while not_finished */
  731.  
  732. }  /* ends get_edge_options */
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.    /***********************************************
  740.     *
  741.     *    fix_edges(...
  742.     *
  743.     *    This function fixes the edges of an image
  744.     *    array after convolution was performed.
  745.     *    It copies the points near the edge of the
  746.     *    array out to the edge of the array.
  747.     *
  748.     ***********************************************/
  749.  
  750.  
  751.  
  752. fix_edges(im, w)
  753.       int   w;
  754.       short im[ROWS][COLS];
  755. {
  756.    int i, j;
  757.  
  758.  
  759.       /* four corners */
  760.    for(i=w; i>0; i--){
  761.     im[i-1][i-1] = im[i][i];
  762.     im[i-1][COLS-(i-1)] = im[i][COLS-1-(i-1)];
  763.     im[ROWS-(i-1)][i-1] = im[ROWS-1-(i-1)][i];
  764.     im[ROWS-(i-1)][COLS-(i-1)] = im[ROWS-1-(i-1)][COLS-1-(i-1)];
  765.    }  /* ends four corners loop */
  766.  
  767.    for(i=0; i<ROWS; i++){
  768.       for(j=w; j>0; j--){
  769.        im[i][j-1] = im[i][j];
  770.        im[i][COLS-j] = im[i][COLS-j-1];
  771.       }
  772.    }
  773.  
  774.    for(j=0; j<COLS; j++){
  775.       for(i=w; i>0; i--){
  776.        im[i-1][j] = im[i][j];
  777.        im[ROWS-i][j] = im[ROWS-i-1][j];
  778.       }
  779.    }
  780.  
  781. }  /* ends fix_edges */
  782.  
  783.     /***********************************************
  784.     *
  785.     *    file d:\cips\edge2.c
  786.     *
  787.     *    Functions: This file contains
  788.     *       homogeneity
  789.     *       difference_edge
  790.     *       contrast_edge
  791.     *       range
  792.     *       variance
  793.     *
  794.     *    Purpose:
  795.     *       These functions implement several
  796.     *       types of advanced edge detection.
  797.     *
  798.     *    External Calls:
  799.     *       wtiff.c - round_off_image_size
  800.     *                 create_file_if_needed
  801.     *                 write_array_into_tiff_image
  802.     *       tiff.c - read_tiff_header
  803.     *       rtiff.c - read_tiff_image
  804.     *       numcvrt.c - get_integer
  805.     *       edge.c - fix_edges
  806.     *
  807.     *    Modifications:
  808.     *       26 March 1991 - created
  809.     *       30 December 1992 - added the range and
  810.     *           variance edge detectors.
  811.     *
  812.     *************************************************/
  813.  
  814.  
  815.  
  816. short e_mask[3][3] = {
  817.        {-9,  0, -9},
  818.        { 0, 36,  0},
  819.        {-9,  0, -9} };
  820.  
  821. short contrast[3][3] = {
  822.    {  1,  1,  1},
  823.    {  1,  1,  1},
  824.    {  1,  1,  1}};
  825.  
  826.  
  827.    /**************************************************
  828.    *
  829.    *   homogeneity(...
  830.    *
  831.    *   This function performs edge detection by looking
  832.    *   for the absence of an edge.  The center of a
  833.    *   3x3 area is replaced by the absolute value of
  834.    *   the max difference between the center point
  835.    *   and its 8 neighbors.
  836.    *
  837.    ***************************************************/
  838.  
  839.  
  840. homogeneity(in_name, out_name, the_image, out_image,
  841.              il, ie, ll, le, threshold, high)
  842.    char   in_name[], out_name[];
  843.    int    high, il, ie, ll, le, threshold;
  844.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  845. {
  846.    int a, b, absdiff, absmax, diff, i, j,
  847.        length, max, max_diff, new_hi, new_low, width;
  848.  
  849.    struct tiff_header_struct image_header;
  850.  
  851.    create_file_if_needed(in_name, out_name, out_image);
  852.  
  853.    read_tiff_header(in_name, &image_header);
  854.  
  855.    new_hi  = 250;
  856.    new_low = 16;
  857.    if(image_header.bits_per_pixel == 4){
  858.        new_hi  = 10;
  859.        new_low = 3;
  860.    }
  861.  
  862.    max = 255;
  863.    if(image_header.bits_per_pixel == 4)
  864.       max = 16;
  865.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  866.  
  867.    for(i=0; i<ROWS; i++)
  868.       if( (i%10) == 0) printf("%3d", i);
  869.       for(j=0; j<COLS; j++)
  870.          out_image[i][j] = 0;
  871.  
  872.    for(i=1; i<ROWS-1; i++){
  873.       for(j=1; j<COLS-1; j++){
  874.  
  875.           max_diff = 0;
  876.           for(a=-1; a<=1; a++){
  877.              for(b=-1; b<=1; b++){
  878.  
  879.                 diff = the_image[i][j] - 
  880.                         the_image[i+a][j+b];
  881.                 absdiff = abs(diff);
  882.                 if(absdiff > max_diff) 
  883.                    max_diff = absdiff;
  884.  
  885.              }  /* ends loop over b */
  886.           }  /* ends loop over a */
  887.  
  888.           out_image[i][j] = max_diff;
  889.       }  /* ends loop over j */
  890.    }  /* ends loop over i */
  891.  
  892.  
  893.      /* if desired, threshold the output image */
  894.    if(threshold == 1){
  895.        for(i=0; i<ROWS; i++){
  896.           for(j=0; j<COLS; j++){
  897.              if(out_image[i][j] > high){
  898.                   out_image[i][j] = new_hi;
  899.              }
  900.              else{
  901.                   out_image[i][j] = new_low;
  902.              }
  903.           }
  904.        }
  905.    }  /* ends if threshold == 1 */
  906.  
  907.    fix_edges(out_image, 1);
  908.  
  909.    write_array_into_tiff_image(out_name, out_image,
  910.                                il, ie, ll, le);
  911.  
  912.  
  913. } /* ends homogeneity */
  914.  
  915.  
  916.  
  917.  
  918.    /**************************************************
  919.    *
  920.    *   difference_edge(...
  921.    *
  922.    *   This function performs edge detection by looking
  923.    *   at the differences in the pixels that surround
  924.    *   the center point of a 3x3 area.  It replaces the
  925.    *   center point with the absolute value of the
  926.    *   max difference of:
  927.    *      upper left - lower right
  928.    *      upper right - lower left
  929.    *      left - right
  930.    *      top - bottom
  931.    *
  932.    ***************************************************/
  933.  
  934. difference_edge(in_name, out_name, the_image, out_image,
  935.                 il, ie, ll, le, threshold, high)
  936.    char   in_name[], out_name[];
  937.    int    high, il, ie, ll, le, threshold;
  938.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  939. {
  940.    int a, b, absdiff, absmax, diff, i, j,
  941.        length, max, max_diff, new_hi, new_low, width;
  942.  
  943.    struct tiff_header_struct image_header;
  944.  
  945.  
  946.    create_file_if_needed(in_name, out_name, out_image);
  947.  
  948.    read_tiff_header(in_name, &image_header);
  949.  
  950.    new_hi  = 250;
  951.    new_low = 16;
  952.    if(image_header.bits_per_pixel == 4){
  953.        new_hi  = 10;
  954.        new_low = 3;
  955.    }
  956.  
  957.    max = 255;
  958.    if(image_header.bits_per_pixel == 4)
  959.       max = 16;
  960.  
  961.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  962.  
  963.    for(i=0; i<ROWS; i++)
  964.       for(j=0; j<COLS; j++)
  965.          out_image[i][j] = 0;
  966.  
  967.    for(i=1; i<ROWS-1; i++){
  968.       if( (i%10) == 0) printf("%3d", i);
  969.       for(j=1; j<COLS-1; j++){
  970.  
  971.           max_diff = 0;
  972.           absdiff = abs(the_image[i-1][j-1] -
  973.                          the_image[i+1][j+1]);
  974.           if(absdiff > max_diff) max_diff = absdiff;
  975.  
  976.           absdiff = abs(the_image[i-1][j+1] -
  977.                          the_image[i+1][j-1]);
  978.           if(absdiff > max_diff) max_diff = absdiff;
  979.  
  980.           absdiff = abs(the_image[i][j-1] -
  981.                          the_image[i][j+1]);
  982.           if(absdiff > max_diff) max_diff = absdiff;
  983.  
  984.           absdiff = abs(the_image[i-1][j] -
  985.                          the_image[i+1][j]);
  986.           if(absdiff > max_diff) max_diff = absdiff;
  987.  
  988.  
  989.           out_image[i][j] = max_diff;
  990.  
  991.       }  /* ends loop over j */
  992.    }  /* ends loop over i */
  993.  
  994.  
  995.  
  996.      /* if desired, threshold the output image */
  997.    if(threshold == 1){
  998.        for(i=0; i<ROWS; i++){
  999.           for(j=0; j<COLS; j++){
  1000.              if(out_image[i][j] > high){
  1001.                   out_image[i][j] = new_hi;
  1002.              }
  1003.              else{
  1004.                   out_image[i][j] = new_low;
  1005.              }
  1006.           }
  1007.        }
  1008.    }  /* ends if threshold == 1 */
  1009.  
  1010.  
  1011.  
  1012.    fix_edges(out_image, 1);
  1013.    write_array_into_tiff_image(out_name, out_image,
  1014.                                il, ie, ll, le);
  1015.  
  1016.  
  1017. } /* ends difference_edge */
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.    /**************************************************
  1024.    *
  1025.    *   contrast_edge(...
  1026.    *
  1027.    *   The edge detector uses the basic quick edge
  1028.    *   detector mask and then divides the result
  1029.    *   by a contrast smooth mask.  This implements
  1030.    *   Johnson's contrast based edge detector.
  1031.    *
  1032.    ***************************************************/
  1033.  
  1034. contrast_edge(in_name, out_name, the_image, out_image,
  1035.                 il, ie, ll, le, threshold, high)
  1036.    char   in_name[], out_name[];
  1037.    int    high, il, ie, ll, le, threshold;
  1038.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  1039. {
  1040.    int ad, d;
  1041.    int a, b, absdiff, absmax, diff, i, j,
  1042.        length, max, new_hi, new_low, 
  1043.        sum_d, sum_n, width;
  1044.  
  1045.    struct tiff_header_struct image_header;
  1046.  
  1047.  
  1048.    create_file_if_needed(in_name, out_name, out_image);
  1049.  
  1050.    read_tiff_header(in_name, &image_header);
  1051.  
  1052.    new_hi  = 250;
  1053.    new_low = 16;
  1054.    if(image_header.bits_per_pixel == 4){
  1055.        new_hi  = 10;
  1056.        new_low = 3;
  1057.    }
  1058.  
  1059.    max = 255;
  1060.    if(image_header.bits_per_pixel == 4)
  1061.       max = 16;
  1062.  
  1063.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  1064.  
  1065.    for(i=0; i<ROWS; i++)
  1066.       for(j=0; j<COLS; j++)
  1067.          out_image[i][j] = 0;
  1068.  
  1069.    for(i=1; i<ROWS-1; i++){
  1070.       if( (i%10) == 0) printf("%3d", i);
  1071.       for(j=1; j<COLS-1; j++){
  1072.  
  1073.          sum_n = 0;
  1074.          sum_d = 0;
  1075.  
  1076.          for(a=-1; a<2; a++){
  1077.             for(b=-1; b<2; b++){
  1078.                sum_n = sum_n + the_image[i+a][j+b] *
  1079.                        e_mask[a+1][b+1];
  1080.                sum_d = sum_d + the_image[i+a][j+b] *
  1081.                        contrast[a+1][b+1];
  1082.             }
  1083.          }
  1084.  
  1085.          d = sum_d / 9;
  1086.          if(d == 0)
  1087.             d = 1;
  1088.  
  1089.          out_image[i][j] = sum_n/d;
  1090.  
  1091.          if(out_image[i][j] > max) 
  1092.             out_image[i][j] = max;
  1093.          if(out_image[i][j] < 0) 
  1094.             out_image[i][j] = 0;
  1095.  
  1096.  
  1097.       }  /* ends loop over j */
  1098.    }  /* ends loop over i */
  1099.  
  1100.  
  1101.  
  1102.      /* if desired, threshold the output image */
  1103.    if(threshold == 1){
  1104.        for(i=0; i<ROWS; i++){
  1105.           for(j=0; j<COLS; j++){
  1106.              if(out_image[i][j] > high){
  1107.                   out_image[i][j] = new_hi;
  1108.              }
  1109.              else{
  1110.                   out_image[i][j] = new_low;
  1111.              }
  1112.           }
  1113.        }
  1114.    }  /* ends if threshold == 1 */
  1115.  
  1116.  
  1117.    fix_edges(out_image, 1);
  1118.    write_array_into_tiff_image(out_name, out_image,
  1119.                                il, ie, ll, le);
  1120.  
  1121. } /* ends contrast_edge */
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.      /*******************************************
  1128.      *
  1129.      *   range(..
  1130.      *
  1131.      *   This edge detector performs the
  1132.      *   range operation.
  1133.      *   It replaces the pixel at the center of a
  1134.      *   3x3, 5x5, etc. area with the max - min
  1135.      *   for that area.
  1136.      *
  1137.      *******************************************/
  1138.  
  1139. range(in_name, out_name, the_image, out_image,
  1140.       il, ie, ll, le, size, threshold, high)
  1141.    char   in_name[], out_name[];
  1142.    int    il, ie, ll, le,
  1143.           high, threshold, size;
  1144.    short  the_image[ROWS][COLS],
  1145.           out_image[ROWS][COLS];
  1146.  
  1147. {
  1148.    int    a, b, count, i, j, k,
  1149.           new_hi, new_low, length,
  1150.           sd2, sd2p1, ss, width;
  1151.    short  *elements;
  1152.    struct tiff_header_struct image_header;
  1153.  
  1154.    sd2   = size/2;
  1155.    sd2p1 = sd2 + 1;
  1156.  
  1157.       /**********************************************
  1158.       *
  1159.       *   Allocate the elements array large enough
  1160.       *   to hold size*size shorts.
  1161.       *
  1162.       **********************************************/
  1163.  
  1164.    ss       = size*size;
  1165.    elements = (short *) malloc(ss * sizeof(short));
  1166.  
  1167.    create_file_if_needed(in_name, out_name, out_image);
  1168.  
  1169.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  1170.  
  1171.    new_hi  = 250;
  1172.    new_low = 16;
  1173.    if(image_header.bits_per_pixel == 4){
  1174.        new_hi  = 10;
  1175.        new_low = 3;
  1176.    }
  1177.  
  1178.       /***************************
  1179.       *
  1180.       *   Loop over image array
  1181.       *
  1182.       ****************************/
  1183.  
  1184.    printf("\n");
  1185.    for(i=sd2; i<ROWS-sd2; i++){
  1186.       if( (i%10) == 0) printf("%d ", i);
  1187.       for(j=sd2; j<COLS-sd2; j++){
  1188.          count = 0;
  1189.          for(a=-sd2; a<sd2p1; a++){
  1190.             for(b=-sd2; b<sd2p1; b++){
  1191.                elements[count] = the_image[i+a][j+b];
  1192.                count++;
  1193.             }
  1194.          }
  1195.          sort_elements(elements, &ss);
  1196.          out_image[i][j] = elements[ss-1]-elements[0];
  1197.       }  /* ends loop over j */
  1198.    }  /* ends loop over i */
  1199.  
  1200.      /* if desired, threshold the output image */
  1201.    if(threshold == 1){
  1202.        for(i=0; i<ROWS; i++){
  1203.           for(j=0; j<COLS; j++){
  1204.              if(out_image[i][j] > high){
  1205.                   out_image[i][j] = new_hi;
  1206.              }
  1207.              else{
  1208.                   out_image[i][j] = new_low;
  1209.              }
  1210.           }
  1211.        }
  1212.    }  /* ends if threshold == 1 */
  1213.  
  1214.    fix_edges(out_image, sd2);
  1215.  
  1216.    write_array_into_tiff_image(out_name, out_image,
  1217.                                il, ie, ll, le);
  1218.  
  1219.    free(elements);
  1220.  
  1221. }  /* ends range */
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.    /**************************************************
  1228.    *
  1229.    *   variance(...
  1230.    *
  1231.    *   This function replaces the pixel in the center
  1232.    *   of a 3x3 area with the square root of the sum 
  1233.    *   of squares of the differences between the 
  1234.    *   center pixel and its eight neighbors.
  1235.    *
  1236.    ***************************************************/
  1237.  
  1238. variance(in_name, out_name, the_image, out_image,
  1239.          il, ie, ll, le, threshold, high)
  1240.    char   in_name[], out_name[];
  1241.    int    il, ie, ll, le, high, threshold;
  1242.    short  the_image[ROWS][COLS],
  1243.           out_image[ROWS][COLS];
  1244. {
  1245.    int      a, b, i, j, length,
  1246.             max, new_hi, new_low, width;
  1247.    long     diff;
  1248.    unsigned long sum, tmp;
  1249.  
  1250.    struct tiff_header_struct image_header;
  1251.  
  1252.  
  1253.    create_file_if_needed(in_name, out_name, out_image);
  1254.  
  1255.    read_tiff_header(in_name, &image_header);
  1256.  
  1257.    new_hi  = 250;
  1258.    new_low = 16;
  1259.    if(image_header.bits_per_pixel == 4){
  1260.        new_hi  = 10;
  1261.        new_low = 3;
  1262.    }
  1263.  
  1264.    max = 255;
  1265.    if(image_header.bits_per_pixel == 4)
  1266.       max = 16;
  1267.  
  1268.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  1269.  
  1270.    for(i=1; i<ROWS-1; i++){
  1271.       if( (i%10) == 0) printf("%3d", i);
  1272.       for(j=1; j<COLS-1; j++){
  1273.          sum = 0;
  1274.          for(a=-1; a<=1; a++){
  1275.              for(b=-1; b<=1; b++){
  1276.                 if( a!=0  &&  b!=0){
  1277.                  diff = 0;
  1278.                  diff = the_image[i][j] -
  1279.                         the_image[i+a][j+b];
  1280.                  tmp = diff*diff;
  1281.                  sum = sum + tmp;
  1282.                 }
  1283.              }
  1284.          }
  1285.          if(sum < 0)
  1286.             printf("\nWHAT? sum < 0, %ld ,diff=%d ", sum, diff);
  1287.          sum = sqrt(sum);
  1288.          if(sum > max) sum = max;
  1289.          out_image[i][j] = sum;
  1290.       }  /* ends loop over j */
  1291.    }  /* ends loop over i */
  1292.  
  1293.       /* if desired, threshold the output image */
  1294.    if(threshold == 1){
  1295.        for(i=0; i<ROWS; i++){
  1296.           for(j=0; j<COLS; j++){
  1297.              if(out_image[i][j] > high){
  1298.                   out_image[i][j] = new_hi;
  1299.              }
  1300.              else{
  1301.                   out_image[i][j] = new_low;
  1302.              }
  1303.           }
  1304.        }
  1305.    }  /* ends if threshold == 1 */
  1306.  
  1307.  
  1308.    fix_edges(out_image, 1);
  1309.    write_array_into_tiff_image(out_name, out_image,
  1310.                                il, ie, ll, le);
  1311.  
  1312. } /* ends variance */
  1313.  
  1314.  
  1315.     /***********************************************
  1316.     *
  1317.     *    file d:\cips\edge3.c
  1318.     *
  1319.     *    Functions: This file contains
  1320.     *       gaussian_edge
  1321.     *       enhance_edges
  1322.     *
  1323.     *    Purpose:
  1324.     *       These functions implement several
  1325.     *       types of advanced edge detection.
  1326.     *
  1327.     *    External Calls:
  1328.     *       wtiff.c - round_off_image_size
  1329.     *                 create_file_if_needed
  1330.     *                 write_array_into_tiff_image
  1331.     *                 round_off_image_size
  1332.     *       tiff.c - read_tiff_header
  1333.     *       rtiff.c - read_tiff_image
  1334.     *       numcvrt.c - get_integer
  1335.     *       edge.c - fix_edges
  1336.     *
  1337.     *    Modifications:
  1338.     *       26 March 1991 - created
  1339.     *
  1340.     ***********************************************/
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349. short enhance_mask[3][3] =  {
  1350.        {-1,  0, -1},
  1351.        { 0,  4,  0},
  1352.        {-1,  0, -1} };
  1353.  
  1354.  
  1355.  
  1356. short g7[7][7] = {
  1357.      {  0,  0, -1, -1, -1,  0,  0},
  1358.      {  0, -2, -3, -3, -3, -2,  0},
  1359.      { -1, -3,  5,  5,  5, -3, -1},
  1360.      { -1, -3,  5, 16,  5, -3, -1},
  1361.      { -1, -3,  5,  5,  5, -3, -1},
  1362.      {  0, -2, -3, -3, -3, -2,  0},
  1363.      {  0,  0, -1, -1, -1,  0,  0}};
  1364.  
  1365. short g9[9][9] = {
  1366.    {  0,  0,  0,  -1, -1, -1,  0,  0,  0},
  1367.    {  0, -2, -3,  -3, -3, -3, -3, -2,  0},
  1368.    {  0, -3, -2,  -1, -1, -1, -2, -3,  0},
  1369.    { -1, -3, -1,   9,  9,  9, -1, -3, -1},
  1370.    { -1, -3, -1,   9, 19,  9, -1, -3, -1},
  1371.    { -1, -3, -1,   9,  9,  9, -1, -3, -1},
  1372.    {  0, -3, -2,  -1, -1, -1, -2, -3,  0},
  1373.    {  0, -2, -3,  -3, -3, -3, -3, -2,  0},
  1374.    {  0,  0,  0,  -1, -1, -1,  0,  0,  0}};
  1375.  
  1376.  
  1377.  
  1378.    /************************************************
  1379.    *
  1380.    *   gaussian_edge(...
  1381.    *
  1382.    *
  1383.    *************************************************/
  1384.  
  1385. gaussian_edge(in_name, out_name, the_image, out_image,
  1386.               il, ie, ll, le, size, threshold, high)
  1387.    char   in_name[], out_name[];
  1388.    int    high, il, ie, ll, le, size, threshold;
  1389.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  1390. {
  1391.    char response[80];
  1392.    long sum;
  1393.    int  a, b, absdiff, absmax, diff, i, j,
  1394.         length, lower, max, new_hi, new_low,
  1395.         scale, start, stop, upper, width;
  1396.  
  1397.    struct tiff_header_struct image_header;
  1398.  
  1399.  
  1400.    create_file_if_needed(in_name, out_name, out_image);
  1401.  
  1402.    read_tiff_header(in_name, &image_header);
  1403.  
  1404.    new_hi  = 250;
  1405.    new_low = 16;
  1406.    if(image_header.bits_per_pixel == 4){
  1407.        new_hi  = 10;
  1408.        new_low = 3;
  1409.    }
  1410.  
  1411.    max = 255;
  1412.    if(image_header.bits_per_pixel == 4)
  1413.       max = 16;
  1414.  
  1415.  
  1416.    if(size == 7){
  1417.       lower = -3;
  1418.       upper =  4;
  1419.       start =  3;
  1420.       stop  =  ROWS-3;
  1421.       scale =  2;
  1422.    }
  1423.  
  1424.    if(size == 9){
  1425.       lower = -4;
  1426.       upper =  5;
  1427.       start =  4;
  1428.       stop  =  ROWS-4;
  1429.       scale =  2;
  1430.    }
  1431.  
  1432.  
  1433.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  1434.  
  1435.    for(i=0; i<ROWS; i++)
  1436.       for(j=0; j<COLS; j++)
  1437.          out_image[i][j] = 0;
  1438.  
  1439.  
  1440.    for(i=start; i<stop; i++){
  1441.       if ( (i%10) == 0) printf(" i=%d", i);
  1442.       for(j=start; j<stop; j++){
  1443.  
  1444.       sum = 0;
  1445.  
  1446.       for(a=lower; a<upper; a++){
  1447.          for(b=lower; b<upper; b++){
  1448.             if(size == 7)
  1449.                sum = sum + the_image[i+a][j+b] *
  1450.                      g7[a+3][b+3];
  1451.             if(size == 9)
  1452.                sum = sum + the_image[i+a][j+b] *
  1453.                      g9[a+4][b+4];
  1454.          } /* ends loop over a */
  1455.       }  /* ends loop over b */
  1456.  
  1457.       if(sum < 0) sum = 0;
  1458.       if(sum > max) sum = max;
  1459.       out_image[i][j] = sum;
  1460.  
  1461.  
  1462.       }  /* ends loop over j */
  1463.    }  /* ends loop over i */
  1464.  
  1465.      /* if desired, threshold the output image */
  1466.    if(threshold == 1){
  1467.        for(i=0; i<ROWS; i++){
  1468.           for(j=0; j<COLS; j++){
  1469.              if(out_image[i][j] > high){
  1470.                   out_image[i][j] = new_hi;
  1471.              }
  1472.              else{
  1473.                   out_image[i][j] = new_low;
  1474.              }
  1475.           }
  1476.        }
  1477.    }  /* ends if threshold == 1 */
  1478.  
  1479.  
  1480.    fix_edges(out_image, size/2);
  1481.  
  1482.    write_array_into_tiff_image(out_name, out_image,
  1483.                                il, ie, ll, le);
  1484.  
  1485. } /* ends gaussian_edge */
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.      /*******************************************
  1493.      *
  1494.      * enhance_edges(...
  1495.      *
  1496.      * This function enhances the edges in an
  1497.      * input image and writes the enhanced
  1498.      * result to an output image.  It operates
  1499.      * much the same way as detect_edges
  1500.      * except it uses only one type of mask.
  1501.      *
  1502.      * The threshold and high parameters perform
  1503.      * a different role in this function.  The
  1504.      * threshold parameter does not exist.  The
  1505.      * high parameter determines if the edge is
  1506.      * strong enough to enhance or change the
  1507.      * input image.
  1508.      *
  1509.      *******************************************/
  1510.  
  1511.  
  1512. enhance_edges(in_name, out_name, the_image, out_image,
  1513.              il, ie, ll, le, high)
  1514.    char   in_name[], out_name[];
  1515.    int    high, il, ie, ll, le;
  1516.    short  the_image[ROWS][COLS], out_image[ROWS][COLS];
  1517.  
  1518. {
  1519.    int    a, b, i, j, k,
  1520.           length, max, new_hi,
  1521.           new_lo, sum, width;
  1522.    struct tiff_header_struct image_header;
  1523.  
  1524.  
  1525.    create_file_if_needed(in_name, out_name, out_image);
  1526.  
  1527.    read_tiff_header(in_name, &image_header);
  1528.  
  1529.    max = 255;
  1530.    if(image_header.bits_per_pixel == 4)
  1531.       max = 16;
  1532.  
  1533.  
  1534.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  1535.  
  1536.          /* Do convolution over image array */
  1537.    for(i=1; i<ROWS-1; i++){
  1538.       if( (i%10) == 0) printf("%d ", i);
  1539.       for(j=1; j<COLS-1; j++){
  1540.          sum = 0;
  1541.          for(a=-1; a<2; a++){
  1542.             for(b=-1; b<2; b++){
  1543.                sum = sum +
  1544.                      the_image[i+a][j+b] *
  1545.                      enhance_mask[a+1][b+1];
  1546.             }
  1547.          }
  1548.          if(sum < 0)   sum = 0;
  1549.          if(sum > max) sum = max;
  1550.          if(sum > high)
  1551.             out_image[i][j] = max;
  1552.          else
  1553.             out_image[i][j] = the_image[i][j];
  1554.       }  /* ends loop over j */
  1555.    }  /* ends loop over i */
  1556.  
  1557.    fix_edges(out_image, 1);
  1558.  
  1559.  
  1560.    write_array_into_tiff_image(out_name, out_image,
  1561.                                il, ie, ll, le);
  1562. }  /* ends enhance_edges */
  1563.